<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/ice.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/ice.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"yoursite.com","root":"/","scheme":"Gemini","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":true,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":true,"trigger":"auto","top_n_per_article":3,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.xml"};
  </script>

  <meta name="description" content="配置相关JavaConfigSpring JavaConfig 是 Spring 社区的产品，它提供了配置 Spring IoC 容器的纯 Java 方法，因此它有助于避免使用 XML 配置。使用 JavaConfig 的优点在于：  面向对象的配置。 由于配置被定义为 JavaConfig 中的类，因此用户可以充分利用 Java 中的面向对象功能。一个配置类可以继承另一个，重写它的@Bean 方">
<meta property="og:type" content="article">
<meta property="og:title" content="SpringBoot基础">
<meta property="og:url" content="http://yoursite.com/2020/06/23/Java%E6%A1%86%E6%9E%B6/SpringBoot/index.html">
<meta property="og:site_name" content="严冰的博客">
<meta property="og:description" content="配置相关JavaConfigSpring JavaConfig 是 Spring 社区的产品，它提供了配置 Spring IoC 容器的纯 Java 方法，因此它有助于避免使用 XML 配置。使用 JavaConfig 的优点在于：  面向对象的配置。 由于配置被定义为 JavaConfig 中的类，因此用户可以充分利用 Java 中的面向对象功能。一个配置类可以继承另一个，重写它的@Bean 方">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2020-06-23T12:50:49.000Z">
<meta property="article:modified_time" content="2020-07-01T10:56:40.335Z">
<meta property="article:author" content="yanbing">
<meta property="article:tag" content="SpringBoot">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="http://yoursite.com/2020/06/23/Java%E6%A1%86%E6%9E%B6/SpringBoot/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>SpringBoot基础 | 严冰的博客</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

<link rel="alternate" href="/atom.xml" title="严冰的博客" type="application/atom+xml">
</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">严冰的博客</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>

  </li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div id="search-result">
  <div id="no-result">
    <i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
  </div>
</div>

    </div>
  </div>

</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2020/06/23/Java%E6%A1%86%E6%9E%B6/SpringBoot/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/dog.jpg">
      <meta itemprop="name" content="yanbing">
      <meta itemprop="description" content="闲看庭前花开落，漫随天外云卷舒。">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="严冰的博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          SpringBoot基础
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2020-06-23 20:50:49" itemprop="dateCreated datePublished" datetime="2020-06-23T20:50:49+08:00">2020-06-23</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2020-07-01 18:56:40" itemprop="dateModified" datetime="2020-07-01T18:56:40+08:00">2020-07-01</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Java%E6%A1%86%E6%9E%B6/" itemprop="url" rel="index"><span itemprop="name">Java框架</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h2 id="配置相关"><a href="#配置相关" class="headerlink" title="配置相关"></a>配置相关</h2><h3 id="JavaConfig"><a href="#JavaConfig" class="headerlink" title="JavaConfig"></a>JavaConfig</h3><p>Spring JavaConfig 是 Spring 社区的产品，它提供了配置 Spring IoC 容器的纯 Java 方法，因此它有助于避免使用 XML 配置。使用 JavaConfig 的优点在于：</p>
<ul>
<li><p>面向对象的配置。</p>
<p>由于配置被定义为 JavaConfig 中的类，因此用户可以充分利用 Java 中的面向对象功能。一个配置类可以继承另一个，重写它的@Bean 方法等。</p>
</li>
<li><p>减少或消除 XML 配置。</p>
<p>许多开发人员不希望在 XML 和 Java 之间来回切换。JavaConfig 为开发人员提供了一种纯 Java 方法来配置与 XML 配置概念相似的 Spring 容器。从技术角度来讲，只使用 JavaConfig 配置类来配置容器是可行的，但实际上很多人认为将JavaConfig 与 XML 混合匹配是理想的。</p>
</li>
<li><p>类型安全和重构友好。</p>
<p>JavaConfig 提供了一种类型安全的方法来配置 Spring容器。由于 Java 5.0 对泛型的支持，现在可以按类型而不是按名称检索 bean，不需要任何强制转换或基于字符串的查找。</p>
<a id="more"></a>
<h3 id="配置加载顺序"><a href="#配置加载顺序" class="headerlink" title="配置加载顺序"></a>配置加载顺序</h3></li>
</ul>
<p>在 Spring Boot 里面，可以使用以下几种方式来加载配置。</p>
<ol>
<li><p>properties文件</p>
</li>
<li><p>YAML文件</p>
</li>
<li><p>系统环境变量</p>
</li>
<li><p>命令行参数</p>
</li>
</ol>
<h3 id="核心配置文件"><a href="#核心配置文件" class="headerlink" title="核心配置文件"></a>核心配置文件</h3><ul>
<li>bootstrap (. yml 或者 . properties)：boostrap 由 ApplicationContext 加载，比 applicaton 优先加载，配置在应用程序上下文的引导阶段生效。一般来说我们在 Spring Cloud Config 或者 Nacos 中会用到它，且 boostrap 里面的属性不能被覆盖</li>
<li>application (. yml 或者 . properties)：由ApplicatonContext 加载，用于 spring boot 项目的自动化配置</li>
</ul>
<h3 id="YAML-配置文件"><a href="#YAML-配置文件" class="headerlink" title="YAML 配置文件"></a>YAML 配置文件</h3><p>YAML 是一种人类可读的数据序列化语言，它通常用于配置文件。与属性文件相比，如果我们想要在配置文件中添加复杂的属性，YAML 文件就更加结构化，而且更少混淆。 YAML 具有分层配置数据。YAML 配置和传统的 properties 配置相比有如下优势：</p>
<ol>
<li>配置有序，在一些特殊的场景下，配置有序很关键</li>
<li>支持数组，数组中的元素可以是基本数据类型也可以是对象</li>
<li>简洁</li>
</ol>
<p>相比 properties 配置文件，YAML 还有一个缺点，就是不支持 @PropertySource 注解导入自定义的 YAML 配置。</p>
<h3 id="XML配置文件"><a href="#XML配置文件" class="headerlink" title="XML配置文件"></a>XML配置文件</h3><p>Spring Boot 推荐使用 Java 配置而非 XML 配置，但是 Spring Boot 中也可以使用 XML 配置，通过 @ImportResource 注解可以引入一个 XML 配置。</p>
<h3 id="Spring-Profiles"><a href="#Spring-Profiles" class="headerlink" title="Spring Profiles"></a>Spring Profiles</h3><p>Spring Profiles 允许用户根据配置文件（dev，test，prod 等）来注册 bean。因此，当应用程序在开发中运行时，只有某些 bean 可以加载，而在 PRODUCTION中，某些其他 bean 可以加载。</p>
<h2 id="安全相关"><a href="#安全相关" class="headerlink" title="安全相关"></a>安全相关</h2><h3 id="实现安全性"><a href="#实现安全性" class="headerlink" title="实现安全性"></a>实现安全性</h3><p>为了实现 Spring Boot 的安全性，使用 spring-boot-starter-security 依赖项，并且必须添加安全配置，它只需要很少的代码。配置类将必须扩展WebSecurityConfigurerAdapter 并覆盖其方法。</p>
<h3 id="Spring-Security-和-Shiro-的优缺点"><a href="#Spring-Security-和-Shiro-的优缺点" class="headerlink" title="Spring Security 和 Shiro 的优缺点"></a>Spring Security 和 Shiro 的优缺点</h3><p>如果是 Spring Boot 项目，一般选择 Spring Security ，当然这只是一个建议的组合，单纯从技术上来说，无论怎么组合，都是没有问题的。</p>
<ol>
<li>Spring Security 是一个重量级的安全管理框架；Shiro 则是一个轻量级的安全管理框架</li>
<li>Spring Security 概念复杂，配置繁琐；Shiro 概念简单、配置简单</li>
<li>Spring Security 功能强大；Shiro 功能简单</li>
</ol>
<h2 id="监视器"><a href="#监视器" class="headerlink" title="监视器"></a>监视器</h2><h3 id="什么是监视器"><a href="#什么是监视器" class="headerlink" title="什么是监视器"></a>什么是监视器</h3><p>Spring boot actuator 是 spring 启动框架中的重要功能之一。Spring boot 监视器可帮助您访问生产环境中正在运行的应用程序的当前状态。有几个指标必须在生产环境中进行检查和监控。即使一些外部应用程序可能正在使用这些服务来向相关人员触发警报消息。监视器模块公开了一组可直接作为 HTTP URL 访问的REST 端点来检查状态。</p>
<h2 id="常用注解"><a href="#常用注解" class="headerlink" title="常用注解"></a>常用注解</h2><h3 id="1-启动相关"><a href="#1-启动相关" class="headerlink" title="1.启动相关"></a>1.启动相关</h3><h4 id="1-1-SpringBootApplication"><a href="#1-1-SpringBootApplication" class="headerlink" title="1.1 @SpringBootApplication"></a>1.1 <code>@SpringBootApplication</code></h4><p>这个注解是 Spring Boot 项目的基石，创建 SpringBoot 项目之后会默认在主类加上。</p>
<p>我们可以把 <code>@SpringBootApplication</code>看作是 <code>@Configuration</code>、<code>@EnableAutoConfiguration</code>、<code>@ComponentScan</code> 注解的集合。</p>
<p>根据 SpringBoot 官网，这三个注解的作用分别是：</p>
<ul>
<li><code>@EnableAutoConfiguration</code>：启用 SpringBoot 的自动配置机制</li>
<li><code>@ComponentScan</code>：扫描被<code>@Component</code> (<code>@Service</code>, <code>@Controller</code> ,<code>@Repository</code>)注解的 bean，注解默认会扫描==该类所在的包下所有的类==。</li>
<li><code>@Configuration</code>：允许在 Spring 上下文中注册额外的 bean 或导入其他配置类</li>
</ul>
<h3 id="2-Spring-Bean-相关"><a href="#2-Spring-Bean-相关" class="headerlink" title="2. Spring Bean 相关"></a>2. Spring Bean 相关</h3><h4 id="2-1-Autowired"><a href="#2-1-Autowired" class="headerlink" title="2.1. @Autowired"></a>2.1. <code>@Autowired</code></h4><p>自动导入对象到类中，被注入进的类同样要被 Spring 容器管理。</p>
<p>例如：将Service 类注入到 Controller 类中。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UserService</span> </span>&#123;</span><br><span class="line">  ......</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/users"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UserController</span> </span>&#123;</span><br><span class="line">   <span class="meta">@Autowired</span></span><br><span class="line">   <span class="keyword">private</span> UserService userService;</span><br><span class="line">   ......</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="2-2-Component-Repository-Service-Controller"><a href="#2-2-Component-Repository-Service-Controller" class="headerlink" title="2.2. @Component, @Repository, @Service,  @Controller"></a>2.2. <code>@Component</code>, <code>@Repository</code>, <code>@Service</code>,  <code>@Controller</code></h4><p>我们一般使用 <code>@Autowired</code> 注解让 Spring 容器帮我们自动装配 bean，要想把类标识成可用于 <code>@Autowired</code> 注解自动装配的 bean 的类，可以采用以下注解实现：</p>
<ul>
<li><code>@Component</code> ：通用的注解，可标注==任意类==为 <code>Spring</code> 组件。如果一个 bean 不知道属于哪个层，可以使用<code>@Component</code> 注解标注。</li>
<li><code>@Repository</code> : 对应==持久层==即 Dao 层，主要用于数据库相关操作。</li>
<li><code>@Service</code> : 对应==服务层==，主要涉及一些复杂的逻辑，需要用到 Dao 层。</li>
<li><code>@Controller</code> : 对应 Spring MVC ==控制层==，主要用户接受用户请求并调用 Service 层返回数据给前端页面。</li>
</ul>
<h4 id="2-3-RestController-Controller-ResponseBody"><a href="#2-3-RestController-Controller-ResponseBody" class="headerlink" title="2.3. @RestController,  @Controller + @ResponseBody"></a>2.3. <code>@RestController</code>,  <code>@Controller</code> + <code>@ResponseBody</code></h4><p><code>@RestController</code>注解是<code>@Controller和</code>@<code>ResponseBody</code>的合集,表示这是个控制器 bean,并且是==将函数的返回值直接填入 HTTP 响应体中==,是 REST 风格的控制器。</p>
<p>单独使用 <code>@Controller</code> 不加 <code>@ResponseBody</code>的话一般使用在要==返回一个视图==的情况，这种情况属于比较传统的 Spring MVC 的应用，对应于前后端不分离的情况。</p>
<p><code>@Controller</code> + <code>@ResponseBody</code> 返回 JSON 或 XML 形式数据，即==只返回对象==，对象数据直接以 JSON 或 XML 形式写入 HTTP 响应(Response)中，这种情况属于 RESTful Web服务，这也是目前日常开发所接触的最常用的情况（前后端分离）。</p>
<blockquote>
<p>  如果在Spring4之前开发 RESTful Web服务的话，则需要使用<code>@Controller</code> 并结合<code>@ResponseBody</code>注解，也就是说<code>@Controller</code> +<code>@ResponseBody</code>= <code>@RestController</code>，<code>@RestController</code>是Spring 4 之后新加的注解</p>
</blockquote>
<p><code>@ResponseBody</code> 注解的作用是将 <code>Controller</code> 的方法返回的对象通过适当的转换器转换为指定的格式之后，写入到HTTP 响应(Response)对象的 body 中，通常用来返回 JSON 或者 XML 数据，返回 JSON 数据的情况比较多。</p>
<h5 id="示例1-Controller-返回一个页面"><a href="#示例1-Controller-返回一个页面" class="headerlink" title="示例1: @Controller 返回一个页面"></a>示例1: @Controller 返回一个页面</h5><p>当我们需要直接在后端返回一个页面的时候，Spring 推荐使用 Thymeleaf 模板引擎。Spring MVC中<code>@Controller</code>中的方法可以直接返回模板名称，接下来 Thymeleaf 模板引擎会自动进行渲染,模板中的表达式支持Spring表达式语言（Spring EL)。如果需要用到 Thymeleaf 模板引擎，需要添加依赖。</p>
<p><strong>Maven:</strong></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-thymeleaf<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><code>src/main/java/com/example/demo/controller/HelloController.java</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Controller</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HelloController</span> </span>&#123;</span><br><span class="line">    <span class="meta">@GetMapping</span>(<span class="string">"/hello"</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">greeting</span><span class="params">(@RequestParam(name = <span class="string">"name"</span>, required = <span class="keyword">false</span>, defaultValue = <span class="string">"World"</span>)</span> String name, Model model) </span>&#123;</span><br><span class="line">        model.addAttribute(<span class="string">"name"</span>, name);</span><br><span class="line">        <span class="keyword">return</span> <span class="string">"hello"</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>src/main/resources/templates/hello.html</code></p>
<p>Spring 默认会去 resources 目录下 templates 目录下找，所以建议把页面放在 resources/templates 目录下</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="meta-keyword">HTML</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">xmlns:th</span>=<span class="string">"http://www.thymeleaf.org"</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>Getting Started: Serving Web Content<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">http-equiv</span>=<span class="string">"Content-Type"</span> <span class="attr">content</span>=<span class="string">"text/html; charset=UTF-8"</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">p</span> <span class="attr">th:text</span>=<span class="string">"'Hello, ' + $&#123;name&#125; + '!'"</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>访问：<a href="http://localhost:8999/hello?name=team-c" target="_blank" rel="noopener">http://localhost:8999/hello?name=team-c</a> ，将看到下面的内容</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Hello, team-c!</span><br></pre></td></tr></table></figure>

<p>如果要对页面在templates目录下的hello文件夹中的页面话，返回页面的时候像下面这样写就可以了：</p>
<p><code>src/main/resources/templates/hello/hello.html</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Controller</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HelloController</span> </span>&#123;</span><br><span class="line">    <span class="meta">@GetMapping</span>(<span class="string">"/hello"</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">greeting</span><span class="params">(@RequestParam(name = <span class="string">"name"</span>, required = <span class="keyword">false</span>, defaultValue = <span class="string">"World"</span>)</span> String name, Model model) </span>&#123;</span><br><span class="line">        model.addAttribute(<span class="string">"name"</span>, name);</span><br><span class="line">        <span class="keyword">return</span> <span class="string">"hello/hello"</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="示例2-Controller-ResponseBody-返回-JSON-格式数据"><a href="#示例2-Controller-ResponseBody-返回-JSON-格式数据" class="headerlink" title="示例2: @Controller+@ResponseBody 返回 JSON 格式数据"></a>示例2: @Controller+@ResponseBody 返回 JSON 格式数据</h5><p>SpringBoot 默认集成了 jackson ,因此不需要添加任何相关依赖。</p>
<p><code>src/main/java/com/example/demo/controller/Person.java</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Person</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> Integer age;</span><br><span class="line">    <span class="comment">//......</span></span><br><span class="line">    <span class="comment">//省略getter/setter ，有参和无参的construtor方法</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>src/main/java/com/example/demo/controller/HelloController.java</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Controller</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HelloController</span> </span>&#123;</span><br><span class="line">    <span class="meta">@PostMapping</span>(<span class="string">"/hello"</span>)</span><br><span class="line">    <span class="meta">@ResponseBody</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Person <span class="title">greeting</span><span class="params">(@RequestBody Person person)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> person;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>使用 post 请求访问 <a href="http://localhost:8080/hello" target="_blank" rel="noopener">http://localhost:8080/hello</a> ，body 中附带以下参数,后端会以json 格式将 person 对象返回。</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">    <span class="attr">"name"</span>: <span class="string">"teamc"</span>,</span><br><span class="line">    <span class="attr">"age"</span>: <span class="number">1</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h5 id="示例3-RestController-返回-JSON-格式数据"><a href="#示例3-RestController-返回-JSON-格式数据" class="headerlink" title="示例3: @RestController 返回 JSON 格式数据"></a>示例3: @RestController 返回 JSON 格式数据</h5><p>只需要将<code>HelloController</code>改为如下形式：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HelloController</span> </span>&#123;</span><br><span class="line">    <span class="meta">@PostMapping</span>(<span class="string">"/hello"</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> Person <span class="title">greeting</span><span class="params">(@RequestBody Person person)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> person;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="2-4-Scope"><a href="#2-4-Scope" class="headerlink" title="2.4. @Scope"></a>2.4. <code>@Scope</code></h4><p>声明 Spring Bean 的作用域，使用方法:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Bean</span></span><br><span class="line"><span class="meta">@Scope</span>(<span class="string">"singleton"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> Person <span class="title">personSingleton</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> Person();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>四种常见的 Spring Bean 的作用域：</strong></p>
<ul>
<li>singleton : 唯一 bean 实例，Spring 中的 bean 默认都是单例的。</li>
<li>prototype : 每次请求都会创建一个新的 bean 实例。</li>
<li>request : 每一次 HTTP 请求都会产生一个新的 bean，该 bean 仅在当前 HTTP request 内有效。</li>
<li>session : 每一次 HTTP 请求都会产生一个新的 bean，该 bean 仅在当前 HTTP session 内有效。</li>
</ul>
<h4 id="2-5-Configuration"><a href="#2-5-Configuration" class="headerlink" title="2.5. Configuration"></a>2.5. <code>Configuration</code></h4><p>一般用来声明配置类，可以使用 <code>@Component</code>注解替代，不过使用<code>Configuration</code>注解声明配置类更加语义化。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">AppConfig</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> TransferService <span class="title">transferService</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> TransferServiceImpl();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="3-处理常见的-HTTP-请求"><a href="#3-处理常见的-HTTP-请求" class="headerlink" title="3. 处理常见的 HTTP 请求"></a>3. 处理常见的 HTTP 请求</h3><p><strong>5 种常见的请求类型:</strong></p>
<ul>
<li><strong>GET</strong> ：请求从服务器获取特定资源。举个例子：<code>GET /users</code>（获取所有学生）</li>
<li><strong>POST</strong> ：在服务器上创建一个新的资源。举个例子：<code>POST /users</code>（创建学生）</li>
<li><strong>PUT</strong> ：更新服务器上的资源（客户端提供更新后的整个资源）。举个例子：<code>PUT /users/12</code>（更新编号为 12 的学生）</li>
<li><strong>DELETE</strong> ：从服务器删除特定的资源。举个例子：<code>DELETE /users/12</code>（删除编号为 12 的学生）</li>
<li><strong>PATCH</strong> ：更新服务器上的资源（客户端提供更改的属性，可以看做作是部分更新），使用的比较少。</li>
</ul>
<h4 id="3-1-GET-请求"><a href="#3-1-GET-请求" class="headerlink" title="3.1. GET 请求"></a>3.1. GET 请求</h4><p><code>@GetMapping(&quot;users&quot;)</code> 等价于 <code>@RequestMapping(value=&quot;/users&quot;,method=RequestMethod.GET)</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@GetMapping</span>(<span class="string">"/users"</span>)</span><br><span class="line"><span class="keyword">public</span> ResponseEntity&lt;List&lt;User&gt;&gt; getAllUsers() &#123;</span><br><span class="line">	<span class="keyword">return</span> userRepository.findAll();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="3-2-POST-请求"><a href="#3-2-POST-请求" class="headerlink" title="3.2. POST 请求"></a>3.2. POST 请求</h4><p><code>@PostMapping(&quot;users&quot;)</code> 等价于<code>@RequestMapping(value=&quot;/users&quot;,method=RequestMethod.POST)</code></p>
<p>关于<code>@RequestBody</code>注解的使用，在下面的“前后端传值”这块会讲到。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PostMapping</span>(<span class="string">"/users"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> ResponseEntity&lt;User&gt; <span class="title">createUser</span><span class="params">(@Valid @RequestBody UserCreateRequest userCreateRequest)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> userRespository.save(user);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="3-3-PUT-请求"><a href="#3-3-PUT-请求" class="headerlink" title="3.3. PUT 请求"></a>3.3. PUT 请求</h4><p><code>@PutMapping(&quot;/users/{userId}&quot;)</code> 等价于<code>@RequestMapping(value=&quot;/users/{userId}&quot;,method=RequestMethod.PUT)</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PutMapping</span>(<span class="string">"/users/&#123;userId&#125;"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> ResponseEntity&lt;User&gt; <span class="title">updateUser</span><span class="params">(@PathVariable(value = <span class="string">"userId"</span>)</span> Long userId, @Valid @RequestBody UserUpdateRequest userUpdateRequest) </span>&#123;</span><br><span class="line">	<span class="comment">//......</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="3-4-DELETE-请求"><a href="#3-4-DELETE-请求" class="headerlink" title="3.4. DELETE 请求"></a>3.4. <strong>DELETE 请求</strong></h4><p><code>@DeleteMapping(&quot;/users/{userId}&quot;)</code>等价于<code>@RequestMapping(value=&quot;/users/{userId}&quot;,method=RequestMethod.DELETE)</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@DeleteMapping</span>(<span class="string">"/users/&#123;userId&#125;"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> ResponseEntity <span class="title">deleteUser</span><span class="params">(@PathVariable(value = <span class="string">"userId"</span>)</span> Long userId)</span>&#123;</span><br><span class="line">	<span class="comment">//......</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="3-5-PATCH-请求"><a href="#3-5-PATCH-请求" class="headerlink" title="3.5. PATCH 请求"></a>3.5. <strong>PATCH 请求</strong></h4><p>一般实际项目中，我们都是 PUT 不够用了之后才用 PATCH 请求去更新数据。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PatchMapping</span>(<span class="string">"/profile"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> ResponseEntity <span class="title">updateStudent</span><span class="params">(@RequestBody StudentUpdateRequest studentUpdateRequest)</span> </span>&#123;</span><br><span class="line">	studentRepository.updateDetail(studentUpdateRequest);</span><br><span class="line">	<span class="keyword">return</span> ResponseEntity.ok().build();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="4-前后端传值"><a href="#4-前后端传值" class="headerlink" title="4. 前后端传值"></a>4. 前后端传值</h3><p>掌握前后端传值的正确姿势，是开始 CRUD 的第一步！</p>
<h4 id="4-1-PathVariable-和-RequestParam"><a href="#4-1-PathVariable-和-RequestParam" class="headerlink" title="4.1. @PathVariable 和 @RequestParam"></a>4.1. <code>@PathVariable</code> 和 <code>@RequestParam</code></h4><p><code>@PathVariable</code>用于获取路径中的参数，<code>@RequestParam</code>用于获取查询中的参数（<code>?</code>后面的参数）。</p>
<p>举个简单的例子：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@GetMapping</span>(<span class="string">"/klasses/&#123;klassId&#125;/teachers"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Teacher&gt; <span class="title">getKlassRelatedTeachers</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">         @PathVariable(<span class="string">"klassId"</span>)</span> Long klassId,</span></span><br><span class="line"><span class="function">         @<span class="title">RequestParam</span><span class="params">(value = <span class="string">"type"</span>, required = <span class="keyword">false</span>)</span> String type ) </span>&#123;</span><br><span class="line">	<span class="comment">//...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>如果我们请求的 url 是：<code>/klasses/{123456}/teachers?type=web</code></p>
<p>那么我们服务获取到的数据就是：<code>klassId=123456,type=web</code>。</p>
<h4 id="4-2-RequestBody"><a href="#4-2-RequestBody" class="headerlink" title="4.2. @RequestBody"></a>4.2. <code>@RequestBody</code></h4><p>用于读取 Request 请求（可能是 POST,PUT,DELETE,GET 请求）的 body 部分并且<strong>Content-Type 为 application/json</strong> 格式的数据，接收到数据之后会自动将数据绑定到 Java 对象上去。系统会使用<code>HttpMessageConverter</code>或者自定义的<code>HttpMessageConverter</code>将请求的 body 中的 json 字符串转换为 java对象。</p>
<p>例如：我们有一个注册的接口：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PostMapping</span>(<span class="string">"/sign-up"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> ResponseEntity <span class="title">signUp</span><span class="params">(@RequestBody @Valid UserRegisterRequest userRegisterRequest)</span> </span>&#123;</span><br><span class="line">	userService.save(userRegisterRequest);</span><br><span class="line">	<span class="keyword">return</span> ResponseEntity.ok().build();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>UserRegisterRequest</code>对象：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Data</span></span><br><span class="line"><span class="meta">@AllArgsConstructor</span></span><br><span class="line"><span class="meta">@NoArgsConstructor</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UserRegisterRequest</span> </span>&#123;</span><br><span class="line">    <span class="meta">@NotBlank</span></span><br><span class="line">    <span class="keyword">private</span> String userName;</span><br><span class="line">    <span class="meta">@NotBlank</span></span><br><span class="line">    <span class="keyword">private</span> String password;</span><br><span class="line">    <span class="meta">@FullName</span></span><br><span class="line">    <span class="meta">@NotBlank</span></span><br><span class="line">    <span class="keyword">private</span> String fullName;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>我们发送 post 请求到这个接口，并且 body 携带 JSON 数据：</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">    <span class="attr">"userName"</span>:<span class="string">"coder"</span>,</span><br><span class="line">    <span class="attr">"fullName"</span>:<span class="string">"shuangkou"</span>,</span><br><span class="line">    <span class="attr">"password"</span>:<span class="string">"123456"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这样我们的后端就可以直接把 json 格式的数据映射到我们的 <code>UserRegisterRequest</code> 类上。</p>
<blockquote>
<p>  需要注意的是：<strong>一个请求方法只可以有一个<code>@RequestBody</code>，但是可以有多个<code>@RequestParam</code>和<code>@PathVariable</code></strong>。如果你的方法必须要用两个 <code>@RequestBody</code>来接受数据的话，大概率是你的数据库设计或者系统设计出问题了</p>
</blockquote>
<h3 id="5-读取配置信息"><a href="#5-读取配置信息" class="headerlink" title="5. 读取配置信息"></a>5. 读取配置信息</h3><p>很多时候我们需要将一些常用的配置信息比如阿里云 oss、发送短信、微信认证的相关配置信息等等放到配置文件中，下面我们来看一下 Spring 为我们提供了哪些方式帮助我们从配置文件中读取这些配置信息。</p>
<p>数据源<code>application.yml</code>内容如下：：</p>
<figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">wuhan2020:</span> <span class="number">2020</span><span class="string">年初武汉爆发了新型冠状病毒，疫情严重，但是，我相信一切都会过去！武汉加油！中国加油！</span></span><br><span class="line"></span><br><span class="line"><span class="attr">my-profile:</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">Guide哥</span></span><br><span class="line">  <span class="attr">email:</span> <span class="string">koushuangbwcx@163.com</span></span><br><span class="line"></span><br><span class="line"><span class="attr">library:</span></span><br><span class="line">  <span class="attr">location:</span> <span class="string">湖北武汉加油中国加油</span></span><br><span class="line">  <span class="attr">books:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">天才基本法</span></span><br><span class="line">      <span class="attr">description:</span> <span class="string">二十二岁的林朝夕在父亲确诊阿尔茨海默病这天，得知自己暗恋多年的校园男神裴之即将出国深造的消息——对方考取的学校，恰是父亲当年为她放弃的那所。</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">时间的秩序</span></span><br><span class="line">      <span class="attr">description:</span> <span class="string">为什么我们记得过去，而非未来？时间“流逝”意味着什么？是我们存在于时间之内，还是时间存在于我们之中？卡洛·罗韦利用诗意的文字，邀请我们思考这一亘古难题——时间的本质。</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">了不起的我</span></span><br><span class="line">      <span class="attr">description:</span> <span class="string">如何养成一个新习惯？如何让心智变得更成熟？如何拥有高质量的关系？</span> <span class="string">如何走出人生的艰难时刻？</span></span><br></pre></td></tr></table></figure>

<h4 id="5-1-value-常用"><a href="#5-1-value-常用" class="headerlink" title="5.1. @value(常用)"></a>5.1. <code>@value</code>(常用)</h4><p>使用 <code>@Value(&quot;${property}&quot;)</code> 读取比较简单的配置信息：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Value</span>(<span class="string">"$&#123;wuhan2020&#125;"</span>)</span><br><span class="line">String wuhan2020;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>  需要注意的是<code>@value</code>这种方式是不被推荐的，Spring 比较建议的是下面几种读取配置信息的方式。</p>
</blockquote>
<h4 id="5-2-ConfigurationProperties-常用"><a href="#5-2-ConfigurationProperties-常用" class="headerlink" title="5.2. @ConfigurationProperties(常用)"></a>5.2. <code>@ConfigurationProperties</code>(常用)</h4><p>通过<code>@ConfigurationProperties</code>读取配置信息并与 bean 绑定。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="meta">@ConfigurationProperties</span>(prefix = <span class="string">"library"</span>)</span><br><span class="line"><span class="meta">@Setter</span></span><br><span class="line"><span class="meta">@Getter</span></span><br><span class="line"><span class="meta">@ToString</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">LibraryProperties</span> </span>&#123;</span><br><span class="line">    <span class="meta">@NotEmpty</span></span><br><span class="line">    <span class="keyword">private</span> String location;</span><br><span class="line">    <span class="keyword">private</span> List&lt;Book&gt; books;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Setter</span></span><br><span class="line">    <span class="meta">@Getter</span></span><br><span class="line">    <span class="meta">@ToString</span></span><br><span class="line">    <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">Book</span> </span>&#123;</span><br><span class="line">        String name;</span><br><span class="line">        String description;</span><br><span class="line">    &#125;</span><br><span class="line">  	<span class="comment">//省略getter/setter</span></span><br><span class="line">  	<span class="comment">//......</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>  <code>LibraryProperties</code>类上加了<code>@Component</code>注解，我们可以像使用普通 bean 一样将其注入到类中使用。</p>
</blockquote>
<h4 id="5-3-PropertySource（不常用）"><a href="#5-3-PropertySource（不常用）" class="headerlink" title="5.3. PropertySource（不常用）"></a>5.3. <code>PropertySource</code>（不常用）</h4><p><code>@PropertySource</code>读取指定 properties 文件</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="meta">@PropertySource</span>(<span class="string">"classpath:website.properties"</span>)</span><br><span class="line"><span class="meta">@Getter</span></span><br><span class="line"><span class="meta">@Setter</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">WebSite</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Value</span>(<span class="string">"$&#123;url&#125;"</span>)</span><br><span class="line">    <span class="keyword">private</span> String url;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//省略getter/setter</span></span><br><span class="line">  <span class="comment">//......</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>使用：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Autowired</span></span><br><span class="line"><span class="keyword">private</span> WebSite webSite;</span><br><span class="line">System.out.println(webSite.getUrl());<span class="comment">//https://javaguide.cn/</span></span><br></pre></td></tr></table></figure>

<h3 id="6-JSR参数校验"><a href="#6-JSR参数校验" class="headerlink" title="6. JSR参数校验"></a>6. JSR参数校验</h3><p>数据的校验的重要性就不用说了，即使在前端对数据进行校验的情况下，我们还是要对传入后端的数据再进行一遍校验，避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。</p>
<p><strong>JSR(Java Specification Requests）</strong> 是一套 JavaBean 参数校验的标准，它定义了很多常用的校验注解，我们可以直接将这些注解加在我们 JavaBean 的属性上面，这样就可以在需要校验的时候进行校验了。校验的时候我们实际用的是 <strong>Hibernate Validator</strong> 框架。SpringBoot 项目的 spring-boot-starter-web 依赖中已经有 hibernate-validator 包，不需要引用相关依赖。</p>
<blockquote>
<p>  需要注意的是：<strong>所有的注解，推荐使用 JSR 注解，即<code>javax.validation.constraints</code>，而不是<code>org.hibernate.validator.constraints</code></strong></p>
</blockquote>
<h4 id="6-1-一些常用的字段验证的注解"><a href="#6-1-一些常用的字段验证的注解" class="headerlink" title="6.1. 一些常用的字段验证的注解"></a>6.1. 一些常用的字段验证的注解</h4><ul>
<li><code>@NotEmpty</code> 被注释的字符串的不能为 null 也不能为空</li>
<li><code>@NotBlank</code> 被注释的字符串非 null，并且必须包含一个非空白字符</li>
<li><code>@Null</code> 被注释的元素必须为 null</li>
<li><code>@NotNull</code> 被注释的元素必须不为 null</li>
<li><code>@AssertTrue</code> 被注释的元素必须为 true</li>
<li><code>@AssertFalse</code> 被注释的元素必须为 false</li>
<li><code>@Pattern(regex=,flag=)</code>被注释的元素必须符合指定的正则表达式</li>
<li><code>@Email</code> 被注释的元素必须是 Email 格式。</li>
<li><code>@Min(value)</code>被注释的元素必须是一个数字，其值必须大于等于指定的最小值</li>
<li><code>@Max(value)</code>被注释的元素必须是一个数字，其值必须小于等于指定的最大值</li>
<li><code>@DecimalMin(value)</code>被注释的元素必须是一个数字，其值必须大于等于指定的最小值</li>
<li><code>@DecimalMax(value)</code> 被注释的元素必须是一个数字，其值必须小于等于指定的最大值</li>
<li><code>@Size(max=, min=)</code>被注释的元素的大小必须在指定的范围内</li>
<li><code>@Digits (integer, fraction)</code>被注释的元素必须是一个数字，其值必须在可接受的范围内</li>
<li><code>@Past</code>被注释的元素必须是一个过去的日期</li>
<li><code>@Future</code> 被注释的元素必须是一个将来的日期</li>
</ul>
<h4 id="6-2-验证请求体-RequestBody"><a href="#6-2-验证请求体-RequestBody" class="headerlink" title="6.2. 验证请求体(RequestBody)"></a>6.2. 验证请求体(RequestBody)</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Data</span></span><br><span class="line"><span class="meta">@AllArgsConstructor</span></span><br><span class="line"><span class="meta">@NoArgsConstructor</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Person</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@NotNull</span>(message = <span class="string">"classId 不能为空"</span>)</span><br><span class="line">    <span class="keyword">private</span> String classId;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Size</span>(max = <span class="number">33</span>)</span><br><span class="line">    <span class="meta">@NotNull</span>(message = <span class="string">"name 不能为空"</span>)</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Pattern</span>(regexp = <span class="string">"((^Man$|^Woman$|^UGM$))"</span>, message = <span class="string">"sex 值不在可选范围"</span>)</span><br><span class="line">    <span class="meta">@NotNull</span>(message = <span class="string">"sex 不能为空"</span>)</span><br><span class="line">    <span class="keyword">private</span> String sex;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Email</span>(message = <span class="string">"email 格式不正确"</span>)</span><br><span class="line">    <span class="meta">@NotNull</span>(message = <span class="string">"email 不能为空"</span>)</span><br><span class="line">    <span class="keyword">private</span> String email;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>我们在需要验证的参数上加上了<code>@Valid</code>注解，如果验证失败，它将抛出<code>MethodArgumentNotValidException</code>。默认情况下，Spring会将此异常转换为HTTP Status 400（错误请求）。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/api"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">PersonController</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@PostMapping</span>(<span class="string">"/person"</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> ResponseEntity&lt;Person&gt; <span class="title">getPerson</span><span class="params">(@RequestBody @Valid Person person)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> ResponseEntity.ok().body(person);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="6-3-验证请求参数-Path-Variables-和-Request-Parameters"><a href="#6-3-验证请求参数-Path-Variables-和-Request-Parameters" class="headerlink" title="6.3. 验证请求参数(Path Variables 和 Request Parameters)"></a>6.3. 验证请求参数(Path Variables 和 Request Parameters)</h4><p>一定不要忘记在类上加上 <code>Validated</code> 注解了，这个参数可以告诉 Spring 去校验方法参数。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/api"</span>)</span><br><span class="line"><span class="meta">@Validated</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">PersonController</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@GetMapping</span>(<span class="string">"/person/&#123;id&#125;"</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> ResponseEntity&lt;Integer&gt; <span class="title">getPersonByID</span><span class="params">(@Valid @PathVariable(<span class="string">"id"</span>)</span> @<span class="title">Max</span><span class="params">(value = <span class="number">5</span>,message = <span class="string">"超过 id 的范围了"</span>)</span> Integer id) </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> ResponseEntity.ok().body(id);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="7-全局处理-Controller-层异常"><a href="#7-全局处理-Controller-层异常" class="headerlink" title="7. 全局处理 Controller 层异常"></a>7. 全局处理 Controller 层异常</h3><p><strong>相关注解：</strong></p>
<ol>
<li><code>@ControllerAdvice</code> :注解定义全局异常处理类</li>
<li><code>@ExceptionHandler</code> :注解声明异常处理方法</li>
</ol>
<h3 id="8-JPA-相关"><a href="#8-JPA-相关" class="headerlink" title="8. JPA 相关"></a>8. JPA 相关</h3><h4 id="8-1-创建表"><a href="#8-1-创建表" class="headerlink" title="8.1. 创建表"></a>8.1. 创建表</h4><p><code>@Entity</code>声明一个类对应一个数据库实体。</p>
<p><code>@Table</code> 设置表名</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Entity</span></span><br><span class="line"><span class="meta">@Table</span>(name = <span class="string">"role"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Role</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Id</span></span><br><span class="line">    <span class="meta">@GeneratedValue</span>(strategy = GenerationType.IDENTITY)</span><br><span class="line">    <span class="keyword">private</span> Long id;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> String description;</span><br><span class="line">    <span class="comment">//省略getter/setter......</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="8-2-创建主键"><a href="#8-2-创建主键" class="headerlink" title="8.2. 创建主键"></a>8.2. 创建主键</h4><p><code>@Id</code> ：声明一个字段为主键。</p>
<p>使用<code>@Id</code>声明之后，我们还需要定义主键的生成策略。我们可以使用 <code>@GeneratedValue</code> 指定主键生成策略。</p>
<p><strong>1.通过 <code>@GeneratedValue</code>直接使用 JPA 内置提供的四种主键生成策略来指定主键生成策略。</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Id</span></span><br><span class="line"><span class="meta">@GeneratedValue</span>(strategy = GenerationType.IDENTITY)</span><br><span class="line"><span class="keyword">private</span> Long id;</span><br></pre></td></tr></table></figure>

<p>JPA 使用枚举定义了 4 中常见的主键生成策略，<code>@GeneratedValue</code>注解默认使用的策略是<code>GenerationType.AUTO</code>。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">enum</span> GenerationType &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 使用一个特定的数据库表格来保存主键</span></span><br><span class="line"><span class="comment">     * 持久化引擎通过关系数据库的一张特定的表格来生成主键,</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    TABLE,</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     *在某些数据库中,不支持主键自增长,比如Oracle、PostgreSQL其提供了一种叫做"序列(sequence)"的机制生成主键</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    SEQUENCE,</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 主键自增长</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    IDENTITY,</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     *把主键生成策略交给持久化引擎(persistence engine),</span></span><br><span class="line"><span class="comment">     *持久化引擎会根据数据库在以上三种主键生成 策略中选择其中一种</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    AUTO</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>  一般使用 MySQL 数据库的话，使用<code>GenerationType.IDENTITY</code>策略比较普遍一点（分布式系统的话需要另外考虑使用分布式 ID）。</p>
</blockquote>
<p><strong>2.我们可以通过 <code>@GenericGenerator</code>自己声明一个主键策略，然后 <code>@GeneratedValue</code>使用这个策略</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Id</span></span><br><span class="line"><span class="meta">@GeneratedValue</span>(generator = <span class="string">"IdentityIdGenerator"</span>)</span><br><span class="line"><span class="meta">@GenericGenerator</span>(name = <span class="string">"IdentityIdGenerator"</span>, strategy = <span class="string">"identity"</span>)</span><br><span class="line"><span class="keyword">private</span> Long id;</span><br></pre></td></tr></table></figure>

<p>等价于：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Id</span></span><br><span class="line"><span class="meta">@GeneratedValue</span>(strategy = GenerationType.IDENTITY)</span><br><span class="line"><span class="keyword">private</span> Long id;</span><br></pre></td></tr></table></figure>

<p>jpa 提供的主键生成策略有如下几种：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">DefaultIdentifierGeneratorFactory</span></span></span><br><span class="line"><span class="class"><span class="keyword">implements</span> <span class="title">MutableIdentifierGeneratorFactory</span>, <span class="title">Serializable</span>, <span class="title">ServiceRegistryAwareService</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@SuppressWarnings</span>(<span class="string">"deprecation"</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">DefaultIdentifierGeneratorFactory</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        register( <span class="string">"uuid2"</span>, UUIDGenerator<span class="class">.<span class="keyword">class</span> )</span>;</span><br><span class="line">        register( <span class="string">"guid"</span>, GUIDGenerator<span class="class">.<span class="keyword">class</span> )</span>;   <span class="comment">// can be done with UUIDGenerator + strategy</span></span><br><span class="line">        register( <span class="string">"uuid"</span>, UUIDHexGenerator<span class="class">.<span class="keyword">class</span> )</span>;   <span class="comment">// "deprecated" for new use</span></span><br><span class="line">        register( <span class="string">"uuid.hex"</span>, UUIDHexGenerator<span class="class">.<span class="keyword">class</span> )</span>;  <span class="comment">// uuid.hex is deprecated</span></span><br><span class="line">        register( <span class="string">"assigned"</span>, Assigned<span class="class">.<span class="keyword">class</span> )</span>;</span><br><span class="line">        register( <span class="string">"identity"</span>, IdentityGenerator<span class="class">.<span class="keyword">class</span> )</span>;</span><br><span class="line">        register( <span class="string">"select"</span>, SelectGenerator<span class="class">.<span class="keyword">class</span> )</span>;</span><br><span class="line">        register( <span class="string">"sequence"</span>, SequenceStyleGenerator<span class="class">.<span class="keyword">class</span> )</span>;</span><br><span class="line">        register( <span class="string">"seqhilo"</span>, SequenceHiLoGenerator<span class="class">.<span class="keyword">class</span> )</span>;</span><br><span class="line">        register( <span class="string">"increment"</span>, IncrementGenerator<span class="class">.<span class="keyword">class</span> )</span>;</span><br><span class="line">        register( <span class="string">"foreign"</span>, ForeignGenerator<span class="class">.<span class="keyword">class</span> )</span>;</span><br><span class="line">        register( <span class="string">"sequence-identity"</span>, SequenceIdentityGenerator<span class="class">.<span class="keyword">class</span> )</span>;</span><br><span class="line">        register( <span class="string">"enhanced-sequence"</span>, SequenceStyleGenerator<span class="class">.<span class="keyword">class</span> )</span>;</span><br><span class="line">        register( <span class="string">"enhanced-table"</span>, TableGenerator<span class="class">.<span class="keyword">class</span> )</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">register</span><span class="params">(String strategy, Class generatorClass)</span> </span>&#123;</span><br><span class="line">        LOG.debugf( <span class="string">"Registering IdentifierGenerator strategy [%s] -&gt; [%s]"</span>, strategy, generatorClass.getName() );</span><br><span class="line">        <span class="keyword">final</span> Class previous = generatorStrategyToClassNameMap.put( strategy, generatorClass );</span><br><span class="line">        <span class="keyword">if</span> ( previous != <span class="keyword">null</span> ) &#123;</span><br><span class="line">        	LOG.debugf( <span class="string">"    - overriding [%s]"</span>, previous.getName() );</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="8-3-设置字段类型"><a href="#8-3-设置字段类型" class="headerlink" title="8.3. 设置字段类型"></a>8.3. 设置字段类型</h4><p><code>@Column</code> 声明字段。</p>
<p>示例：</p>
<p>设置属性 userName 对应的数据库字段名为 user_name，长度为 32，非空</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Column</span>(name = <span class="string">"user_name"</span>, nullable = <span class="keyword">false</span>, length=<span class="number">32</span>)</span><br><span class="line"><span class="keyword">private</span> String userName;</span><br></pre></td></tr></table></figure>

<p>设置字段类型并且加默认值，这个还是挺常用的。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Column</span>(columnDefinition = <span class="string">"tinyint(1) default 1"</span>)</span><br><span class="line"><span class="keyword">private</span> Boolean enabled;</span><br></pre></td></tr></table></figure>

<h4 id="8-4-指定不持久化特定字段"><a href="#8-4-指定不持久化特定字段" class="headerlink" title="8.4. 指定不持久化特定字段"></a>8.4. 指定不持久化特定字段</h4><p><code>@Transient</code> ：声明不需要与数据库映射的字段，在保存的时候不需要保存进数据库 。</p>
<p>如果我们想让<code>secrect</code> 这个字段不被持久化，可以使用 <code>@Transient</code>关键字声明。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Entity(name=<span class="string">"USER"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">User</span> </span>&#123;</span><br><span class="line">    ......</span><br><span class="line">    <span class="meta">@Transient</span></span><br><span class="line">    <span class="keyword">private</span> String secrect; <span class="comment">// not persistent because of @Transient</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>除了 <code>@Transient</code>关键字声明， 还可以采用下面几种方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">static</span> String secrect; <span class="comment">// not persistent because of static</span></span><br><span class="line"><span class="keyword">final</span> String secrect = “Satish”; <span class="comment">// not persistent because of final</span></span><br><span class="line"><span class="keyword">transient</span> String secrect; <span class="comment">// not persistent because of transient</span></span><br></pre></td></tr></table></figure>

<p>一般使用注解的方式比较多。</p>
<h4 id="8-5-声明大字段"><a href="#8-5-声明大字段" class="headerlink" title="8.5. 声明大字段"></a>8.5. 声明大字段</h4><p><code>@Lob</code>:声明某个字段为大字段。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Lob</span></span><br><span class="line"><span class="keyword">private</span> String content;</span><br></pre></td></tr></table></figure>

<p>更详细的声明：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Lob</span></span><br><span class="line"><span class="comment">//指定 Lob 类型数据的获取策略， FetchType.EAGER 表示非延迟 加载，而 FetchType. LAZY 表示延迟加载 ；</span></span><br><span class="line"><span class="meta">@Basic</span>(fetch = FetchType.EAGER)</span><br><span class="line"><span class="comment">//columnDefinition 属性指定数据表对应的 Lob 字段类型</span></span><br><span class="line"><span class="meta">@Column</span>(name = <span class="string">"content"</span>, columnDefinition = <span class="string">"LONGTEXT NOT NULL"</span>)</span><br><span class="line"><span class="keyword">private</span> String content;</span><br></pre></td></tr></table></figure>

<h4 id="8-6-创建枚举类型的字段"><a href="#8-6-创建枚举类型的字段" class="headerlink" title="8.6. 创建枚举类型的字段"></a>8.6. 创建枚举类型的字段</h4><p>可以使用枚举类型的字段，不过枚举字段要用<code>@Enumerated</code>注解修饰。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">enum</span> Gender &#123;</span><br><span class="line">    MALE(<span class="string">"男性"</span>),</span><br><span class="line">    FEMALE(<span class="string">"女性"</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String value;</span><br><span class="line">    Gender(String str)&#123;</span><br><span class="line">        value=str;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Entity</span></span><br><span class="line"><span class="meta">@Table</span>(name = <span class="string">"role"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Role</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Id</span></span><br><span class="line">    <span class="meta">@GeneratedValue</span>(strategy = GenerationType.IDENTITY)</span><br><span class="line">    <span class="keyword">private</span> Long id;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> String description;</span><br><span class="line">    <span class="meta">@Enumerated</span>(EnumType.STRING)</span><br><span class="line">    <span class="keyword">private</span> Gender gender;</span><br><span class="line">    省略getter/setter......</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>数据库里面对应存储的是 MAIL/FEMAIL。</p>
<h3 id="9-事务-Transactional"><a href="#9-事务-Transactional" class="headerlink" title="9. 事务 @Transactional"></a>9. 事务 <code>@Transactional</code></h3><p>在要开启事务的方法上使用<code>@Transactional</code>注解即可!</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Transactional</span>(rollbackFor = Exception<span class="class">.<span class="keyword">class</span>)</span></span><br><span class="line"><span class="class"><span class="title">public</span> <span class="title">void</span> <span class="title">save</span>() </span>&#123;</span><br><span class="line">  <span class="comment">//......</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>我们知道 Exception 分为运行时异常和非运行时异常。在<code>@Transactional</code>注解中如果不配置<code>rollbackFor</code>属性,那么事物只会在遇到<code>RuntimeException</code>的时候才会回滚,加上<code>rollbackFor=Exception.class</code>,可以让事物在遇到非运行时异常时也回滚。</p>
<p><code>@Transactional</code> 注解一般用在可以作用在类或者方法上。</p>
<ul>
<li><strong>作用于类</strong>：当把<code>@Transactional</code> 注解放在类上时，表示所有该类的<code>public</code> 方法都配置相同的事务属性信息。</li>
<li><strong>作用于方法</strong>：当类配置了<code>@Transactional</code>，方法也配置了<code>@Transactional</code>，方法的事务会覆盖类的事务配置信息。</li>
</ul>
<h3 id="10-json-数据处理"><a href="#10-json-数据处理" class="headerlink" title="10. json 数据处理"></a>10. json 数据处理</h3><h4 id="10-1-过滤-json-数据"><a href="#10-1-过滤-json-数据" class="headerlink" title="10.1. 过滤 json 数据"></a>10.1. 过滤 json 数据</h4><p><code>@JsonIgnoreProperties</code> 作用在类上用于过滤掉特定字段不返回或者不解析。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//生成json时将userRoles属性过滤</span></span><br><span class="line"><span class="meta">@JsonIgnoreProperties</span>(&#123;<span class="string">"userRoles"</span>&#125;)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">User</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String userName;</span><br><span class="line">    <span class="keyword">private</span> String fullName;</span><br><span class="line">    <span class="keyword">private</span> String password;</span><br><span class="line">    <span class="meta">@JsonIgnore</span></span><br><span class="line">    <span class="keyword">private</span> List&lt;UserRole&gt; userRoles = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>@JsonIgnore</code>一般用于类的属性上，作用和上面的<code>@JsonIgnoreProperties</code> 一样。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">User</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String userName;</span><br><span class="line">    <span class="keyword">private</span> String fullName;</span><br><span class="line">    <span class="keyword">private</span> String password;</span><br><span class="line">   <span class="comment">//生成json时将userRoles属性过滤</span></span><br><span class="line">    <span class="meta">@JsonIgnore</span></span><br><span class="line">    <span class="keyword">private</span> List&lt;UserRole&gt; userRoles = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="10-2-格式化-json-数据"><a href="#10-2-格式化-json-数据" class="headerlink" title="10.2. 格式化 json 数据"></a>10.2. 格式化 json 数据</h4><p><code>@JsonFormat</code>一般用来格式化 json 数据。：</p>
<p>比如：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@JsonFormat</span>(shape=JsonFormat.Shape.STRING, pattern=<span class="string">"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"</span>, timezone=<span class="string">"GMT"</span>)</span><br><span class="line"><span class="keyword">private</span> Date date;</span><br></pre></td></tr></table></figure>


    </div>

    
    
    
        

<div>
<ul class="post-copyright">
  <li class="post-copyright-author">
    <strong>本文作者： </strong>yanbing
  </li>
  <li class="post-copyright-link">
    <strong>本文链接：</strong>
    <a href="http://yoursite.com/2020/06/23/Java%E6%A1%86%E6%9E%B6/SpringBoot/" title="SpringBoot基础">http://yoursite.com/2020/06/23/Java框架/SpringBoot/</a>
  </li>
  <li class="post-copyright-license">
    <strong>版权声明： </strong>本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noopener" target="_blank"><i class="fab fa-fw fa-creative-commons"></i>BY-NC-SA</a> 许可协议。转载请注明出处！
  </li>
</ul>
</div>


      <footer class="post-footer">
          
          <div class="post-tags">
              <a href="/tags/SpringBoot/" rel="tag"><i class="fa fa-tag"></i> SpringBoot</a>
          </div>

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2020/06/14/%E5%88%B7%E9%A2%98/%E5%89%91%E6%8C%87offer/" rel="prev" title="剑指offer">
      <i class="fa fa-chevron-left"></i> 剑指offer
    </a></div>
      <div class="post-nav-item">
    <a href="/2020/06/23/Java%E6%A1%86%E6%9E%B6/Spring/" rel="next" title="Spring基础">
      Spring基础 <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#配置相关"><span class="nav-number">1.</span> <span class="nav-text">配置相关</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#JavaConfig"><span class="nav-number">1.1.</span> <span class="nav-text">JavaConfig</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#配置加载顺序"><span class="nav-number">1.2.</span> <span class="nav-text">配置加载顺序</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#核心配置文件"><span class="nav-number">1.3.</span> <span class="nav-text">核心配置文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#YAML-配置文件"><span class="nav-number">1.4.</span> <span class="nav-text">YAML 配置文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#XML配置文件"><span class="nav-number">1.5.</span> <span class="nav-text">XML配置文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Spring-Profiles"><span class="nav-number">1.6.</span> <span class="nav-text">Spring Profiles</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#安全相关"><span class="nav-number">2.</span> <span class="nav-text">安全相关</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#实现安全性"><span class="nav-number">2.1.</span> <span class="nav-text">实现安全性</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Spring-Security-和-Shiro-的优缺点"><span class="nav-number">2.2.</span> <span class="nav-text">Spring Security 和 Shiro 的优缺点</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#监视器"><span class="nav-number">3.</span> <span class="nav-text">监视器</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#什么是监视器"><span class="nav-number">3.1.</span> <span class="nav-text">什么是监视器</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#常用注解"><span class="nav-number">4.</span> <span class="nav-text">常用注解</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-启动相关"><span class="nav-number">4.1.</span> <span class="nav-text">1.启动相关</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#1-1-SpringBootApplication"><span class="nav-number">4.1.1.</span> <span class="nav-text">1.1 @SpringBootApplication</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-Spring-Bean-相关"><span class="nav-number">4.2.</span> <span class="nav-text">2. Spring Bean 相关</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#2-1-Autowired"><span class="nav-number">4.2.1.</span> <span class="nav-text">2.1. @Autowired</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-2-Component-Repository-Service-Controller"><span class="nav-number">4.2.2.</span> <span class="nav-text">2.2. @Component, @Repository, @Service,  @Controller</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-3-RestController-Controller-ResponseBody"><span class="nav-number">4.2.3.</span> <span class="nav-text">2.3. @RestController,  @Controller + @ResponseBody</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#示例1-Controller-返回一个页面"><span class="nav-number">4.2.3.1.</span> <span class="nav-text">示例1: @Controller 返回一个页面</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#示例2-Controller-ResponseBody-返回-JSON-格式数据"><span class="nav-number">4.2.3.2.</span> <span class="nav-text">示例2: @Controller+@ResponseBody 返回 JSON 格式数据</span></a></li><li class="nav-item nav-level-5"><a class="nav-link" href="#示例3-RestController-返回-JSON-格式数据"><span class="nav-number">4.2.3.3.</span> <span class="nav-text">示例3: @RestController 返回 JSON 格式数据</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-4-Scope"><span class="nav-number">4.2.4.</span> <span class="nav-text">2.4. @Scope</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-5-Configuration"><span class="nav-number">4.2.5.</span> <span class="nav-text">2.5. Configuration</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-处理常见的-HTTP-请求"><span class="nav-number">4.3.</span> <span class="nav-text">3. 处理常见的 HTTP 请求</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#3-1-GET-请求"><span class="nav-number">4.3.1.</span> <span class="nav-text">3.1. GET 请求</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-2-POST-请求"><span class="nav-number">4.3.2.</span> <span class="nav-text">3.2. POST 请求</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-3-PUT-请求"><span class="nav-number">4.3.3.</span> <span class="nav-text">3.3. PUT 请求</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-4-DELETE-请求"><span class="nav-number">4.3.4.</span> <span class="nav-text">3.4. DELETE 请求</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-5-PATCH-请求"><span class="nav-number">4.3.5.</span> <span class="nav-text">3.5. PATCH 请求</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-前后端传值"><span class="nav-number">4.4.</span> <span class="nav-text">4. 前后端传值</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#4-1-PathVariable-和-RequestParam"><span class="nav-number">4.4.1.</span> <span class="nav-text">4.1. @PathVariable 和 @RequestParam</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-2-RequestBody"><span class="nav-number">4.4.2.</span> <span class="nav-text">4.2. @RequestBody</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-读取配置信息"><span class="nav-number">4.5.</span> <span class="nav-text">5. 读取配置信息</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#5-1-value-常用"><span class="nav-number">4.5.1.</span> <span class="nav-text">5.1. @value(常用)</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-2-ConfigurationProperties-常用"><span class="nav-number">4.5.2.</span> <span class="nav-text">5.2. @ConfigurationProperties(常用)</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-3-PropertySource（不常用）"><span class="nav-number">4.5.3.</span> <span class="nav-text">5.3. PropertySource（不常用）</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#6-JSR参数校验"><span class="nav-number">4.6.</span> <span class="nav-text">6. JSR参数校验</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#6-1-一些常用的字段验证的注解"><span class="nav-number">4.6.1.</span> <span class="nav-text">6.1. 一些常用的字段验证的注解</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#6-2-验证请求体-RequestBody"><span class="nav-number">4.6.2.</span> <span class="nav-text">6.2. 验证请求体(RequestBody)</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#6-3-验证请求参数-Path-Variables-和-Request-Parameters"><span class="nav-number">4.6.3.</span> <span class="nav-text">6.3. 验证请求参数(Path Variables 和 Request Parameters)</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#7-全局处理-Controller-层异常"><span class="nav-number">4.7.</span> <span class="nav-text">7. 全局处理 Controller 层异常</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#8-JPA-相关"><span class="nav-number">4.8.</span> <span class="nav-text">8. JPA 相关</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#8-1-创建表"><span class="nav-number">4.8.1.</span> <span class="nav-text">8.1. 创建表</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#8-2-创建主键"><span class="nav-number">4.8.2.</span> <span class="nav-text">8.2. 创建主键</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#8-3-设置字段类型"><span class="nav-number">4.8.3.</span> <span class="nav-text">8.3. 设置字段类型</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#8-4-指定不持久化特定字段"><span class="nav-number">4.8.4.</span> <span class="nav-text">8.4. 指定不持久化特定字段</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#8-5-声明大字段"><span class="nav-number">4.8.5.</span> <span class="nav-text">8.5. 声明大字段</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#8-6-创建枚举类型的字段"><span class="nav-number">4.8.6.</span> <span class="nav-text">8.6. 创建枚举类型的字段</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#9-事务-Transactional"><span class="nav-number">4.9.</span> <span class="nav-text">9. 事务 @Transactional</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#10-json-数据处理"><span class="nav-number">4.10.</span> <span class="nav-text">10. json 数据处理</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#10-1-过滤-json-数据"><span class="nav-number">4.10.1.</span> <span class="nav-text">10.1. 过滤 json 数据</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#10-2-格式化-json-数据"><span class="nav-number">4.10.2.</span> <span class="nav-text">10.2. 格式化 json 数据</span></a></li></ol></li></ol></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="yanbing"
      src="/images/dog.jpg">
  <p class="site-author-name" itemprop="name">yanbing</p>
  <div class="site-description" itemprop="description">闲看庭前花开落，漫随天外云卷舒。</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">59</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">14</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">9</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/yanbingzn" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;yanbingzn" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://blog.csdn.net/i_silence" title="CSDN → https:&#x2F;&#x2F;blog.csdn.net&#x2F;i_silence" rel="noopener" target="_blank"><i class="fab fa-codiepie fa-fw"></i>CSDN</a>
      </span>
  </div>
  <div class="cc-license motion-element" itemprop="license">
    <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" class="cc-opacity" rel="noopener" target="_blank"><img src="/images/cc-by-nc-sa.svg" alt="Creative Commons"></a>
  </div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        
  <div class="beian"><a href="http://www.beian.miit.gov.cn/" rel="noopener" target="_blank">豫ICP备20019377号 </a>
  </div>

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">yanbing</span>
</div>

<span id="busuanzi_container_site_uv">
  本站访问次数：<span class="busuanzi-value" id="busuanzi_value_site_pv"></span>
</span>

        
<div class="busuanzi-count">
  <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
    <span class="post-meta-item" id="busuanzi_container_site_uv" style="display: none;">
      <span class="post-meta-item-icon">
        <i class="fa fa-user"></i>
      </span>
      <span class="site-uv" title="总访客量">
        <span id="busuanzi_value_site_uv"></span>
      </span>
    </span>
</div>








      </div>
    </footer>
  </div>

  
  <script size="300" alpha="0.6" zIndex="-1" src="/lib/canvas-ribbon/canvas-ribbon.js"></script>
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>




  
  <script>
    (function(){
      var canonicalURL, curProtocol;
      //Get the <link> tag
      var x=document.getElementsByTagName("link");
		//Find the last canonical URL
		if(x.length > 0){
			for (i=0;i<x.length;i++){
				if(x[i].rel.toLowerCase() == 'canonical' && x[i].href){
					canonicalURL=x[i].href;
				}
			}
		}
    //Get protocol
	    if (!canonicalURL){
	    	curProtocol = window.location.protocol.split(':')[0];
	    }
	    else{
	    	curProtocol = canonicalURL.split(':')[0];
	    }
      //Get current URL if the canonical URL does not exist
	    if (!canonicalURL) canonicalURL = window.location.href;
	    //Assign script content. Replace current URL with the canonical URL
      !function(){var e=/([http|https]:\/\/[a-zA-Z0-9\_\.]+\.baidu\.com)/gi,r=canonicalURL,t=document.referrer;if(!e.test(r)){var n=(String(curProtocol).toLowerCase() === 'https')?"https://sp0.baidu.com/9_Q4simg2RQJ8t7jm9iCKT-xh_/s.gif":"//api.share.baidu.com/s.gif";t?(n+="?r="+encodeURIComponent(document.referrer),r&&(n+="&l="+r)):r&&(n+="?l="+r);var i=new Image;i.src=n}}(window);})();
  </script>




  
<script src="/js/local-search.js"></script>













  

  


  
  <script type="text/javascript"
color="0,0,188" opacity='0.5' zIndex="-1" count="120" src="//cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js"></script>
  

</body>
</html>
